package engine;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

import shape.Circle;
import shape.Line;
import shape.Rectangle;

import engine.SvgObjects;

/**
 * Parses an XML file
 */

public class ReadXMLFile
{
    
    private SvgObjects         svgObjects         = new SvgObjects();
    private Circle             circle;
    private Rectangle          rectangle;
    private Line               line;
    private TranslateSvguUnits translateSvguUnits = new TranslateSvguUnits();
    
    /**
     * This method is xml file and store it as the main objects
     * 
     * @param file
     * @return
     */
    public SvgObjects readIn(String file)
    {
        
        // Starts reading svg file
        
        try
        {
            
            File fSvgFile = new File(file);
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory
                    .newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(fSvgFile);
            doc.getDocumentElement().normalize();
            
            Element documentElement = doc.getDocumentElement();
            
            // check for svg node name
            if (documentElement.getNodeName() != "svg")
            {
                System.out.println("Error.. Document element not svg type ");
                System.exit(0);
            }
            
            // read width if not found return to main
            if (documentElement.hasAttribute("width"))

            svgObjects.setGridWidth(translateSvguUnits.getValue(documentElement
                    .getAttribute("width")));
            else
            {
                System.out.println("No width found...Exiting");
                System.exit(0);
            }
            
            // read height if not found return to main
            
            if (documentElement.hasAttribute("height")) svgObjects
                    .setGridHeight(translateSvguUnits.getValue(documentElement
                            .getAttribute("height")));
            else
            {
                System.out.println("No height found...Exiting");
                System.exit(0);
            }
            
            for (Node child = documentElement.getFirstChild(); child != null; child = child
                    .getNextSibling())
            {
                if (child.getNodeType() == Node.ELEMENT_NODE)
                {
                    Element childElem = (Element) child;
                    
                    String object = childElem.getNodeName();
                    
                    // check svg objects matches our scope of objects that
                    // we are dealing
                    if (!(object.equalsIgnoreCase("rect")
                            || object.equalsIgnoreCase("circle") || object
                            .equalsIgnoreCase("line")))
                    {
                        System.out.println("incorrect Object type ---"
                                + object.toString());
                        System.exit(0);
                        
                    }
                    
                    // if object is a Rectangle create new Rectangle object
                    // and add it in to arraylist
                    if (object.equalsIgnoreCase("rect"))
                    {
                        
                        this.rectangle = null;
                        
                        if ((childElem.hasAttribute("x") && childElem
                                .hasAttribute("y"))
                                && childElem.hasAttribute("width")
                                && childElem.hasAttribute("height")
                                && childElem.hasAttribute("fill")
                                && childElem.hasAttribute("stroke")
                                && childElem.hasAttribute("stroke-width"))
                        {
                            this.rectangle = new Rectangle(
                                    translateSvguUnits.getValue(childElem
                                            .getAttribute("x")),
                                    translateSvguUnits.getValue(childElem
                                            .getAttribute("y")),
                                    translateSvguUnits.getValue(childElem
                                            .getAttribute("width")),
                                    translateSvguUnits.getValue(childElem
                                            .getAttribute("height")),
                                    childElem.getAttribute("fill"),
                                    childElem.getAttribute("stroke"),
                                    translateSvguUnits.getValue(childElem
                                            .getAttribute("stroke-width")));
                            
                        }
                        else if ((childElem.hasAttribute("x") && childElem
                                .hasAttribute("y"))
                                && childElem.hasAttribute("width")
                                && childElem.hasAttribute("height")
                                && childElem.hasAttribute("fill")
                                && childElem.hasAttribute("stroke-width"))
                        {
                            this.rectangle = new Rectangle(
                                    translateSvguUnits.getValue(childElem
                                            .getAttribute("x")),
                                    translateSvguUnits.getValue(childElem
                                            .getAttribute("y")),
                                    translateSvguUnits.getValue(childElem
                                            .getAttribute("width")),
                                    translateSvguUnits.getValue(childElem
                                            .getAttribute("height")),
                                    childElem.getAttribute("fill"),
                                    translateSvguUnits.getValue(childElem
                                            .getAttribute("stroke-width")));
                            
                        }
                        
                        else if ((childElem.hasAttribute("x") && childElem
                                .hasAttribute("y"))
                                && childElem.hasAttribute("width")
                                && childElem.hasAttribute("height")
                                && childElem.hasAttribute("fill"))
                        {
                            this.rectangle = new Rectangle(
                                    translateSvguUnits.getValue(childElem
                                            .getAttribute("x")),
                                    translateSvguUnits.getValue(childElem
                                            .getAttribute("y")),
                                    translateSvguUnits.getValue(childElem
                                            .getAttribute("width")),
                                    translateSvguUnits.getValue(childElem
                                            .getAttribute("height")),
                                    childElem.getAttribute("fill"));
                            
                        }
                        else if ((childElem.hasAttribute("x") && childElem
                                .hasAttribute("y"))
                                && childElem.hasAttribute("width")
                                && childElem.hasAttribute("height"))
                        {
                            this.rectangle = new Rectangle(
                                    translateSvguUnits.getValue(childElem
                                            .getAttribute("x")),
                                    translateSvguUnits.getValue(childElem
                                            .getAttribute("y")),
                                    translateSvguUnits.getValue(childElem
                                            .getAttribute("width")),
                                    translateSvguUnits.getValue(childElem
                                            .getAttribute("height")));
                            
                        }
                        else
                        {
                            
                            System.out.println("Error attribute missing in "
                                    + "Rectangle object...Exiting---"
                                    + object.toString());
                            System.exit(0);
                            
                        }
                        
                        svgObjects.addRectangles(rectangle);
                        
                    }
                    
                    // if object is a circle create new Circle object and
                    // add it in to arraylist
                    
                    if (object.equalsIgnoreCase("circle"))
                    {
                        
                        this.circle = null;
                        
                        if ((childElem.hasAttribute("cx") && childElem
                                .hasAttribute("cy"))
                                && childElem.hasAttribute("r")
                                && childElem.hasAttribute("fill")
                                && childElem.hasAttribute("stroke")
                                && childElem.hasAttribute("stroke-width"))
                        {
                            this.circle = new Circle(
                                    translateSvguUnits.getValue(childElem
                                            .getAttribute("cx")),
                                    translateSvguUnits.getValue(childElem
                                            .getAttribute("cy")),
                                    translateSvguUnits.getValue(childElem
                                            .getAttribute("r")),
                                    childElem.getAttribute("fill"),
                                    childElem.getAttribute("stroke"),
                                    translateSvguUnits.getValue(childElem
                                            .getAttribute("stroke-width")));
                            
                        }
                        else if ((childElem.hasAttribute("cx") && childElem
                                .hasAttribute("cy"))
                                && childElem.hasAttribute("r")
                                && childElem.hasAttribute("fill"))
                        {
                            this.circle = new Circle(
                                    translateSvguUnits.getValue(childElem
                                            .getAttribute("x")),
                                    translateSvguUnits.getValue(childElem
                                            .getAttribute("y")),
                                    translateSvguUnits.getValue(childElem
                                            .getAttribute("r")),
                                    childElem.getAttribute("fill"));
                            
                        }
                        else if ((childElem.hasAttribute("cx") && childElem
                                .hasAttribute("cy"))
                                && childElem.hasAttribute("r"))
                        {
                            this.circle = new Circle(
                                    translateSvguUnits.getValue(childElem
                                            .getAttribute("x")),
                                    translateSvguUnits.getValue(childElem
                                            .getAttribute("y")),
                                    translateSvguUnits.getValue(childElem
                                            .getAttribute("r")));
                            
                        }
                        else
                        {
                            
                            System.out.println("Error attribute missing in "
                                    + "Circle object...Exiting---"
                                    + object.toString());
                            System.exit(0);
                            
                        }
                        
                        svgObjects.addCircles(circle);
                        
                    }
                    
                    // if object is a line create new line object and add it in
                    // to arraylist
                    if (object.equalsIgnoreCase("line"))
                    {
                        
                        this.line = null;
                        
                        if ((childElem.hasAttribute("x1") && childElem
                                .hasAttribute("y1"))
                                && childElem.hasAttribute("x2")
                                && childElem.hasAttribute("y2")
                                && childElem.hasAttribute("stroke")
                                && childElem.hasAttribute("stroke-width"))
                        {
                            this.line = new Line(
                                    translateSvguUnits.getValue(childElem
                                            .getAttribute("x1")),
                                    translateSvguUnits.getValue(childElem
                                            .getAttribute("y1")),
                                    translateSvguUnits.getValue(childElem
                                            .getAttribute("x2")),
                                    translateSvguUnits.getValue(childElem
                                            .getAttribute("y2")),
                                    childElem.getAttribute("stroke"),
                                    translateSvguUnits.getValue(childElem
                                            .getAttribute("stroke-width")));
                            
                        }
                        
                        else if ((childElem.hasAttribute("x1") && childElem
                                .hasAttribute("y1"))
                                && childElem.hasAttribute("x2")
                                && childElem.hasAttribute("y2")
                                && childElem.hasAttribute("stroke-width"))
                        {
                            this.line = new Line(
                                    translateSvguUnits.getValue(childElem
                                            .getAttribute("x1")),
                                    translateSvguUnits.getValue(childElem
                                            .getAttribute("y1")),
                                    translateSvguUnits.getValue(childElem
                                            .getAttribute("x2")),
                                    translateSvguUnits.getValue(childElem
                                            .getAttribute("y2")),
                                    translateSvguUnits.getValue(childElem
                                            .getAttribute("stroke-width")));
                        }
                        
                        else if ((childElem.hasAttribute("x1") && childElem
                                .hasAttribute("y1"))
                                && childElem.hasAttribute("x2")
                                && childElem.hasAttribute("y2"))
                        {
                            this.line = new Line(
                                    translateSvguUnits.getValue(childElem
                                            .getAttribute("x1")),
                                    translateSvguUnits.getValue(childElem
                                            .getAttribute("y1")),
                                    translateSvguUnits.getValue(childElem
                                            .getAttribute("x2")),
                                    translateSvguUnits.getValue(childElem
                                            .getAttribute("y2")));
                            
                        }
                        else
                        {
                            
                            System.out.println("Error attributes missing in "
                                    + "Line object...Exiting---"
                                    + object.toString());
                            System.exit(0);
                            
                        }
                        
                        svgObjects.addLines(line);
                        
                    }
                    
                }
                
            }
            
            return svgObjects;
            
        }
        catch (FileNotFoundException e)
        {
            System.out.println("Error...SVG file not found.");
            e.printStackTrace();
            return null;
        }
        catch (IOException e)
        {
            System.out.println("Error...Unable to read from SVG file.");
            e.printStackTrace();
            return null;
        }
        catch (Exception e)
        {
            System.out.println("Error! SVG paser canot process your svg file.");
            e.printStackTrace();
            return null;
        }
        
    }
    
    /**
     * 
     * @return svgObjects
     */
    
    public SvgObjects getObjectsss()
    {
        return svgObjects;
    }
    
}
